AWS CDKでAmazon FSx for NetApp ONTAPの運用に必要なリソースをまとめてデプロイしてみた

AWS CDKでAmazon FSx for NetApp ONTAPの運用に必要なリソースをまとめてデプロイしてみた

無理なくIaCを適用できそうなところからIaCを使ってみよう
Clock Icon2024.11.22

FSxNを運用する中で使用するリソースをまとめてデプロイしたい

こんにちは、のんピ(@non____97)です。

皆さんはAmazon FSx for NetApp ONTAP(以降FSxN)を運用する中で使用するリソースをまとめてデプロイしたなと思ったことはありますか? 私はあります。

Security Groupで多数のインバウンドルールを管理したり、大量のボリュームに同じようなCloudWatchアラームを設定したり、バックアップ設定を仕込んだりするのは人の手で設定するのは大変です。IaCで管理したいところです。

ということで、AWS CDKでFSxNを運用する中で使用するリソースをまとめてデプロイしてみます。

今回AWS CDKで作成するリソースは以下のとおりです。

  • Prefix List
  • Security Group
  • KMSキー
  • FSxN Volume
  • AWS Backup
  • SNSトピック
  • CloudWatch Alarm

リソースの選定のポイントは以下としました。

  • 認証情報が含まれない
    • SMBサーバードメイン参加時のサービスアカウントのパスワードなど
  • 作成および削除する際に時間がかからない
    • トライandエラーを高速に繰り返すことができるか否か
  • 設定がIaCの定義で完結する
  • 複数環境、複数サイトで複数回作成する可能性が高い
  • 作成し直す場合のインパクトが小さい
  • 作成した後にリソース全体を作り直す可能性が高い

上述の選定ポイントにあまりマッチしないものとして、以下リソースが挙げられます。

  • FSxNファイルシステム
  • FSxN SVM

FSxNファイルシステムやSVMはONTAP CLIなどで設定したい分野が多いところです。LambdaからONTAP REST APIを叩くようなカスタムリソースを設定すれば可能ですが、どうしても手間がかかります。そのため、今回は対象外としました。

なお、ドメイン参加する際の認証情報の受け渡しは以下記事で行なっているようにSecrets ManagerやSSM Parameter Storeなど行えば可能です。

https://dev.classmethod.jp/articles/configure-amazon-fsx-for-netapp-ontap-with-aws-cdk/

AWS CDKのコードの紹介

使用したコードは以下GitHubリポジトリに保存しています。

https://github.com/non-97/aws-cdk-fsxn-resources

ディレクトリツリーは以下のとおりです。

> tree
.
├── .gitignore
├── .npmignore
├── README.md
├── bin
│   └── fsxn-resources.ts
├── cdk.context.json
├── cdk.json
├── jest.config.js
├── lib
│   ├── construct
│   │   ├── backup-construct.ts
│   │   ├── base-construct.ts
│   │   ├── fsxn-volume-construct.ts
│   │   ├── kms-construct.ts
│   │   ├── monitoring-construct.ts
│   │   ├── pl-construct.ts
│   │   └── securitygroup-construct.ts
│   └── fsxn-resources-stack.ts
├── package-lock.json
├── package.json
├── parameter
│   ├── config
│   │   ├── backup-config.ts
│   │   ├── fsxn-filesystem-config.ts
│   │   ├── fsxn-volume-config.ts
│   │   ├── index.ts
│   │   ├── kms-config.ts
│   │   ├── monitoring-config.ts
│   │   ├── pl-config.ts
│   │   ├── securitygroup-config.ts
│   │   ├── system-config.ts
│   │   └── tags-config.ts
│   ├── index.ts
│   └── types
│       └── index.ts
├── test
│   └── fsxn-resources.test.ts
└── tsconfig.json

8 directories, 31 files

/parameter/config内の各リソースに対応した設定ファイルを編集して、デプロイします。

型定義は以下のとおりです。

/parameter/types/index.ts
import * as cdk from "aws-cdk-lib";

// FSxNファイルシステムとSVM関連の情報
export interface FsxnFileSystemProperty {
  fileSystemId: string;               // FSxNファイルシステムのID
  storageVirtualMachineId: string;    // SVMのID
}

// FSxNボリュームの情報
export interface FsxnVolumeProperty {
  name: string;                                                   // ボリュームの名前
  junctionPath: string;                                           // ボリュームのジャンクションパス
  securityStyle: "UNIX" | "NTFS";                                 // セキュリティスタイル
  sizeInMegabytes: string;                                        // ボリュームのサイズ
  snapshotPolicy?: string;                                        // Snapshot Policy
  storageEfficiencyEnabled?: "true" | "false";                    // Storage Efficiencyの有効化有無
  tieringPolicy: cdk.aws_fsx.CfnVolume.TieringPolicyProperty;     // Tiering Policy
}

export interface FsxnVolumesProperty {
  volumes: FsxnVolumeProperty[];
}

// Prefix Listの情報
export interface PrefixListsProperty {
  prefixLists: cdk.aws_ec2.PrefixListProps[];
}

// Security Groupのインバウンドルール
export interface SecurityGroupRuleProperty {
  peer: cdk.aws_ec2.IPeer;      // 送信元
  connection: cdk.aws_ec2.Port; // 送信先ポート
  description: string;          // 説明
}

// Security Groupの情報
export interface SecurityGroupProperty {
  vpcId: string;                          // Security Groupが作成されるVPCのID
  name?: string;                          // Security Groupの名前
  description?: string;                   // 説明
  rules: SecurityGroupRuleProperty[];     // インバウンドルール
}

// KMSキーの情報
export interface KmsKeyProperty {
  alias?: string;                 // KMSキーのエイリアス
  description?: string;           // 説明
  enabled?: boolean;              // 有効か否か
  enableKeyRotation?: boolean;    // 定期的なローテーションを行うか否か
  rotationPeriod?: cdk.Duration;  // ローテーション間隔
}

// Backup Vaultの情報
export interface VaultProperty {
  accessPolicy?: cdk.aws_iam.PolicyDocument;            // アクセスポリシーの定義
  name?: string;                                        // Backup Vaultの名前
  blockRecoveryPointDeletion?: boolean;                 // 復旧ポイントの削除を許可するか否か
  encryptionKeyAlias?: string;                          // 使用するKMSキーのエイリアス
  lockConfiguration?: cdk.aws_backup.LockConfiguration; // Vault Lockの設定
}

export interface BackupProperty {
  backupVault: VaultProperty;
  backupPlanRule: cdk.aws_backup.BackupPlanRuleProps;   // Backup Planのルール
  planName?: string;                                    // Backup Planの名前
  selectionName: string;                                // Backup Selectionの名前
}

// 監視に関連する情報
export interface MonitoringProperty {
  rootVolumeId?: string;                // SVMのルートボリュームのID
  enableInodeUsageMonitoring: boolean;  // inode監視を行うか否か
  enableOkAction?: boolean;             // OK 状態になったタイミングで通知を行うか否か
  topicName?: string;                   // SNS Topicの名前
  emailAddresses?: string[];            // SNS Topicのサブスクリプションとして設定するメールアドレス
}

// 全リソース共通に設定したいタグ
export interface TagProperty {
  key: string;
  value: string;
}

// システム情報
export interface SystemProperty {
  systemName: string;   // システム名
  envName: string;      // 環境名
}

export interface FsxnResourcesProperty {
  systemProperty?: SystemProperty;
  tagsProperty?: TagProperty[];
  fsxnFileSystemProperty?: FsxnFileSystemProperty;
  prefixListsProperty?: PrefixListsProperty;
  securityGroupProperty?: SecurityGroupProperty;
  kmsKeyProperty?: KmsKeyProperty;
  fsxnVolumesProperty?: FsxnVolumesProperty;
  backupProperty?: BackupProperty;
  monitoringProperty?: MonitoringProperty;
}

// CFn Stackのプロパティを表すInterface
export interface FsxnResourcesStackProperty {
  env?: cdk.Environment;
  props: FsxnResourcesProperty;
  tags?: TagProperty[];
}

FSxNを使用するような規模だと、命名規約が決まっていることが多いと思います。

各Constructファイルで命名規約に沿った名前を生成するようにすると、命名規約を変更するときの修正が非常に手間です。

そのため、BaseConstructなるConstructを定義し、各Constructで継承するようにしました。

併せてConstruct IDをPascal Caseにさせるための関数も定義しています。

実際のコードは以下のとおりです。

import { Construct } from "constructs";
import { SystemProperty } from "../../parameter";

export interface BaseConstructProps {
  systemProperty?: SystemProperty;
}

export class BaseConstruct extends Construct {
  private readonly props: Readonly<BaseConstructProps>;
  constructor(scope: Construct, id: string, props: BaseConstructProps) {
    super(scope, id);

    this.props = Object.freeze({ ...props });
  }

  // リソース名の生成
  protected generateResourceName(
    resourceType: string,
    uniqueName?: string,
    delimiter: string = "-",
    pattern: RegExp = /-/g
  ): string {
    if (!this.props.systemProperty) {
      console.log("Unset SystemProperty");
      throw Error;
    }

    const resourceName = `${this.props.systemProperty.systemName}${delimiter}${this.props.systemProperty.envName}${delimiter}${resourceType}`;
    return (
      uniqueName ? `${resourceName}${delimiter}${uniqueName}` : resourceName
    ).replace(pattern, delimiter);
  }

  // Pascal Caseへの変換
  protected toPascalCase(input: string): string {
    if (typeof input !== "string") {
      throw new Error("Input must be a string");
    }

    try {
      if (!input) return "";

      return (
        input
          // "-", "_" " "で単語ごとに分割
          .split(/[-_\s]+/)
          .map((word) => {
            // 空の単語をスキップ
            if (!word) return "";

            // 単語を文字配列に分解して処理
            const chars = word.split("");
            let prevIsUpper = false;

            // 各文字を処理
            const processedChars = chars.map((char, index) => {
              const isUpper = /[A-Z]/.test(char);

              // 最初の文字は大文字に変更
              if (index === 0) {
                prevIsUpper = isUpper;
                return char.toUpperCase();
              }

              // 現在の文字が大文字で、前の文字も大文字だった場合は小文字に変換
              if (isUpper && prevIsUpper) {
                prevIsUpper = true;
                return char.toLowerCase();
              }

              // それ以外の場合は元の状態を保持
              prevIsUpper = isUpper;
              return char;
            });

            return processedChars.join("");
          })
          .join("")
      );
    } catch (error) {
      console.error("Error converting to PascalCase:", error);
      throw error;
    }
  }
}

やってみた

Prefix ListとKMSキーのデプロイ

実際にやってみます。

FSxNファイルシステムやSVMは手動で作成する想定なので、何回かに分けてデプロイします。

まずは、Prefix ListとKMSキーのデプロイです。

以下のように設定します。

/parameter/config/index.ts
import { FsxnResourcesStackProperty } from "../types";
import { systemConfig } from "./system-config";
import { kmsKeyConfig } from "./kms-config";
import { securityGroupConfig } from "./securitygroup-config";
import { prefixListsConfig } from "./pl-config";
import { fsxnFileSystemConfig } from "./fsxn-filesystem-config";
import { backupConfig } from "./backup-config";
import { fsxnVolumesConfig } from "./fsxn-volume-config";
import { monitoringConfig } from "./monitoring-config";
import { tagsConfig } from "./tags-config";

export const fsxnResourcesStackProperty: FsxnResourcesStackProperty = {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION,
  },
  props: {
    systemProperty: systemConfig,
    kmsKeyProperty: kmsKeyConfig,
    prefixListsProperty: prefixListsConfig,
    // securityGroupProperty: securityGroupConfig,
    // fsxnFileSystemProperty: fsxnFileSystemConfig,
    // backupProperty: backupConfig,
    // fsxnVolumesProperty: fsxnVolumesConfig,
    // monitoringProperty: monitoringConfig,
  },
  tags: tagsConfig,
};

export {
  systemConfig,
  kmsKeyConfig,
  prefixListsConfig,
  securityGroupConfig,
  fsxnFileSystemConfig,
  backupConfig,
  fsxnVolumesConfig,
  monitoringConfig,
  tagsConfig,
};
/parameter/config/system-config.ts
import { SystemProperty } from "../types";

export const systemConfig: SystemProperty = {
  systemName: "non-97",
  envName: "dev",
};
/parameter/config/pl-config.ts
import * as cdk from "aws-cdk-lib";
import { PrefixListsProperty } from "../types";

export const prefixListsConfig: PrefixListsProperty = {
  prefixLists: [
    {
      addressFamily: cdk.aws_ec2.AddressFamily.IP_V4,
      entries: [
        { cidr: "10.0.0.10/32" },
        { cidr: "10.0.0.20/32", description: "sample1" },
      ],
      maxEntries: 10,
      prefixListName: "SMB",
    },
    {
      entries: [{ cidr: "10.0.0.30/32" }],
      prefixListName: "ICMP",
    },
  ],
};
/parameter/config/kms-config.ts
import * as cdk from "aws-cdk-lib";
import { KmsKeyProperty } from "../types";

export const kmsKeyConfig: KmsKeyProperty = {
  alias: "fsxn",
  description: "for FSxN File system",
  enabled: true,
  enableKeyRotation: true,
  rotationPeriod: cdk.Duration.days(365),
};

デプロイすると、論理IDがPascal Caseになっていることと、物理IDにnon-97-dev-key-fsxnと命名規約に合うような文字列が設定されていることが確認できます。

1.初回デプロイ.png

Security Groupのデプロイ

次にSecurity Groupのデプロイを行います。

Security Groupのインバウンドルールには作成したPrefix Listも含めるようにします。

/parameter/config/securitygroup-config.ts
import * as cdk from "aws-cdk-lib";
import { SecurityGroupProperty } from "../types";

export const securityGroupConfig: SecurityGroupProperty = {
  vpcId: "vpc-043c0858ea33e8ec2",
  name: "fsxn",
  rules: [
    {
      peer: cdk.aws_ec2.Peer.prefixList("pl-0d1df59eaa666b077"),
      connection: cdk.aws_ec2.Port.SMB,
      description: "SMB",
    },
    {
      peer: cdk.aws_ec2.Peer.prefixList("pl-03be8a39ee35dc634"),
      connection: cdk.aws_ec2.Port.icmpPing(),
      description: "ICMP ping",
    },
    {
      peer: cdk.aws_ec2.Peer.ipv4("10.0.10.10/32"),
      connection: cdk.aws_ec2.Port.SSH,
      description: "SSH",
    },
  ],
};
/parameter/config/index.ts
import { FsxnResourcesStackProperty } from "../types";
import { systemConfig } from "./system-config";
import { kmsKeyConfig } from "./kms-config";
import { securityGroupConfig } from "./securitygroup-config";
import { prefixListsConfig } from "./pl-config";
import { fsxnFileSystemConfig } from "./fsxn-filesystem-config";
import { backupConfig } from "./backup-config";
import { fsxnVolumesConfig } from "./fsxn-volume-config";
import { monitoringConfig } from "./monitoring-config";
import { tagsConfig } from "./tags-config";

export const fsxnResourcesStackProperty: FsxnResourcesStackProperty = {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION,
  },
  props: {
    systemProperty: systemConfig,
    kmsKeyProperty: kmsKeyConfig,
    prefixListsProperty: prefixListsConfig,
    securityGroupProperty: securityGroupConfig,
    // fsxnFileSystemProperty: fsxnFileSystemConfig,
    // backupProperty: backupConfig,
    // fsxnVolumesProperty: fsxnVolumesConfig,
    // monitoringProperty: monitoringConfig,
  },
  tags: tagsConfig,
};

export {
  systemConfig,
  kmsKeyConfig,
  prefixListsConfig,
  securityGroupConfig,
  fsxnFileSystemConfig,
  backupConfig,
  fsxnVolumesConfig,
  monitoringConfig,
  tagsConfig,
};

npx cdk diffをすると、確かに指定したインバウンドルールを持つSecurity Groupを作成してくれそうです。

> npx cdk diff
start: Building 382b132f9cf3a9dbf81b8926dd2fc35e9fd82f49142dbfefa3122ef4e5faded2:<AWSアカウントID>-us-east-1
success: Built 382b132f9cf3a9dbf81b8926dd2fc35e9fd82f49142dbfefa3122ef4e5faded2:<AWSアカウントID>-us-east-1
start: Publishing 382b132f9cf3a9dbf81b8926dd2fc35e9fd82f49142dbfefa3122ef4e5faded2:<AWSアカウントID>-us-east-1
success: Published 382b132f9cf3a9dbf81b8926dd2fc35e9fd82f49142dbfefa3122ef4e5faded2:<AWSアカウントID>-us-east-1
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Stack non-97-dev-stack-fsxn-resources
Security Group Changes
┌───┬───────────────────────────────────────────┬─────┬────────────┬──────────────────────┐
│   │ Group                                     │ Dir │ Protocol   │ Peer                 │
├───┼───────────────────────────────────────────┼─────┼────────────┼──────────────────────┤
│ + │ ${SecurityGroupConstruct/Default.GroupId} │ In  │ TCP 2210.0.10.10/32        │
│ + │ ${SecurityGroupConstruct/Default.GroupId} │ In  │ TCP 445    │ pl-0d1df59eaa666b077 │
│ + │ ${SecurityGroupConstruct/Default.GroupId} │ In  │ ICMP 8--1  │ pl-03be8a39ee35dc634 │
│ + │ ${SecurityGroupConstruct/Default.GroupId} │ Out │ Everything │ Everyone (IPv4)      │
└───┴───────────────────────────────────────────┴─────┴────────────┴──────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Resources
[+] AWS::EC2::SecurityGroup SecurityGroupConstruct/Default SecurityGroupConstructC75D2B69
[+] AWS::EC2::SecurityGroupIngress SecurityGroupConstruct/Default/from pl-0d1df59eaa666b077:445 SecurityGroupConstructfrompl0d1df59eaa666b0774452A5CC07E
[+] AWS::EC2::SecurityGroupIngress SecurityGroupConstruct/Default/from pl-03be8a39ee35dc634:ICMP Type 8 SecurityGroupConstructfrompl03be8a39ee35dc634ICMPType844A35284


✨  Number of stacks with differences: 1

デプロイ後にSecurity Groupを確認すると、意図したルールが設定されていました。

2.2回目デプロイ.png

以上で、FSxNファイルシステムやSVMの作成に必要なリソースのデプロイが完了しました。

ここまで来れば、FSxNファイルシステムとSVMを手動で作成します。

FSxNのボリューム、AWS Backup、SNSトピック、CloudWatchアラームのデプロイ

FSxNファイルシステムとSVM作成後に、FSxNのボリューム、AWS Backup、SNSトピック、CloudWatchアラームをAWS CDKでデプロイします。

各種定義は以下のとおりです。

/parameter/config/fsxn-volume-config.ts
import { FsxnVolumesProperty } from "../types";

export const fsxnVolumesConfig: FsxnVolumesProperty = {
  volumes: [
    {
      name: "vol_test1",
      junctionPath: "/vol_test1",
      securityStyle: "NTFS",
      sizeInMegabytes: "10240",
      snapshotPolicy: "none",
      storageEfficiencyEnabled: "false",
      tieringPolicy: {
        coolingPeriod: 5,
        name: "AUTO",
      },
    },
    {
      name: "vol_test2",
      junctionPath: "/vol_test2",
      securityStyle: "NTFS",
      sizeInMegabytes: "2048",
      snapshotPolicy: "default",
      storageEfficiencyEnabled: "true",
      tieringPolicy: {
        name: "ALL",
      },
    },
  ],
};

/parameter/config/backup-config.ts
import * as cdk from "aws-cdk-lib";
import { BackupProperty } from "../types";

export const backupConfig: BackupProperty = {
  backupVault: {
    name: "fsxn",
    encryptionKeyAlias: "fsxn",
    blockRecoveryPointDeletion: true,
    lockConfiguration: {
      minRetention: cdk.Duration.days(7),
      maxRetention: cdk.Duration.days(90),
      changeableFor: cdk.Duration.days(90),
    },
  },
  backupPlanRule: {
    ruleName: "fsxn",
    startWindow: cdk.Duration.hours(1),
    completionWindow: cdk.Duration.hours(12),
    deleteAfter: cdk.Duration.days(7),
    scheduleExpression: cdk.aws_events.Schedule.cron({
      minute: "40",
      hour: "8",
    }),
  },
  selectionName: "fsxn",
  planName: "fsxn",
};

/parameter/config/monitoring-config.ts
import { MonitoringProperty } from "../types";

export const monitoringConfig: MonitoringProperty = {
  rootVolumeId: "fsvol-06f1c2447518dea35",
  enableInodeUsageMonitoring: true,
  enableOkAction: true,
};

/parameter/config/fsxn-filesystem-config.ts
import { FsxnFileSystemProperty } from "../types";

export const fsxnFileSystemConfig: FsxnFileSystemProperty = {
  fileSystemId: "fs-0e64a4f5386f74c87",
  storageVirtualMachineId: "svm-04f22e3a82142d131",
};

/parameter/config/index.ts
import { FsxnResourcesStackProperty } from "../types";
import { systemConfig } from "./system-config";
import { kmsKeyConfig } from "./kms-config";
import { securityGroupConfig } from "./securitygroup-config";
import { prefixListsConfig } from "./pl-config";
import { fsxnFileSystemConfig } from "./fsxn-filesystem-config";
import { backupConfig } from "./backup-config";
import { fsxnVolumesConfig } from "./fsxn-volume-config";
import { monitoringConfig } from "./monitoring-config";
import { tagsConfig } from "./tags-config";

export const fsxnResourcesStackProperty: FsxnResourcesStackProperty = {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION,
  },
  props: {
    systemProperty: systemConfig,
    kmsKeyProperty: kmsKeyConfig,
    prefixListsProperty: prefixListsConfig,
    securityGroupProperty: securityGroupConfig,
    fsxnFileSystemProperty: fsxnFileSystemConfig,
    backupProperty: backupConfig,
    fsxnVolumesProperty: fsxnVolumesConfig,
    monitoringProperty: monitoringConfig,
  },
  tags: tagsConfig,
};

export {
  systemConfig,
  kmsKeyConfig,
  prefixListsConfig,
  securityGroupConfig,
  fsxnFileSystemConfig,
  backupConfig,
  fsxnVolumesConfig,
  monitoringConfig,
  tagsConfig,
};

npx cdk diffをすると、確かに指定したリソースを作成してくれそうです。

> npx cdk diff
[Warning at /non-97-dev-stack-fsxn-resources/BackupConstruct/Role] [object Object]
start: Building 50daf894d1ad70bc3d29eaea90d8125b8c8f518698680c2af9fd657cb27075bf:<AWSアカウントID>-us-east-1
success: Built 50daf894d1ad70bc3d29eaea90d8125b8c8f518698680c2af9fd657cb27075bf:<AWSアカウントID>-us-east-1
start: Publishing 50daf894d1ad70bc3d29eaea90d8125b8c8f518698680c2af9fd657cb27075bf:<AWSアカウントID>-us-east-1
success: Published 50daf894d1ad70bc3d29eaea90d8125b8c8f518698680c2af9fd657cb27075bf:<AWSアカウントID>-us-east-1
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Stack non-97-dev-stack-fsxn-resources
IAM Statement Changes
┌───┬──────────────────────────────┬────────┬───────────────────────────────────────────────────────────────┬───────────┬───────────┐
│   │ Resource                     │ Effect │ Action                                                        │ Principal │ Condition │
├───┼──────────────────────────────┼────────┼───────────────────────────────────────────────────────────────┼───────────┼───────────┤
│ + │ ${BackupConstruct/Vault.Arn} │ Deny   │ backup:DeleteRecoveryPoint                                    │ AWS:*     │           │
│   │                              │        │ backup:UpdateRecoveryPointLifecycle                           │           │           │
└───┴──────────────────────────────┴────────┴───────────────────────────────────────────────────────────────┴───────────┴───────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Resources
[+] AWS::Backup::BackupVault BackupConstruct/Vault BackupConstructVault75ECEF5F
[+] AWS::Backup::BackupPlan BackupConstruct/BackupPlan BackupConstructBackupPlan467C7241
[+] AWS::Backup::BackupSelection BackupConstruct/BackupSelection BackupConstructBackupSelectionC83DBFF7
[+] AWS::FSx::Volume FsxnVolumeConstruct/VolTest1 FsxnVolumeConstructVolTest1C3E52B23
[+] AWS::FSx::Volume FsxnVolumeConstruct/VolTest2 FsxnVolumeConstructVolTest2D2FEFF56
[+] AWS::SNS::Topic MonitoringConstruct/Topic MonitoringConstructTopic9E0A8832
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsxnFileSystemStorageCapacityUtilization MonitoringConstructAlarmFsxnFileSystemStorageCapacityUtilizationB5337B6D
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsxnFileSystemNetworkThroughputUtilization MonitoringConstructAlarmFsxnFileSystemNetworkThroughputUtilization7AEBF82B
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsxnFileSystemFileServerDiskThroughputUtilization MonitoringConstructAlarmFsxnFileSystemFileServerDiskThroughputUtilizationEFE12F39
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsxnFileSystemDiskIopsUtilization MonitoringConstructAlarmFsxnFileSystemDiskIopsUtilization98F515A9
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsxnFileSystemCpuutilization MonitoringConstructAlarmFsxnFileSystemCpuutilization08E8374A
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsvolVolTest1StorageCapacityUtilization MonitoringConstructAlarmFsvolVolTest1StorageCapacityUtilizationB9753F6E
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsvolVolTest1InodeUtilization MonitoringConstructAlarmFsvolVolTest1InodeUtilization4F19C0BD
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsvolVolTest2StorageCapacityUtilization MonitoringConstructAlarmFsvolVolTest2StorageCapacityUtilizationBF4D8972
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsvolVolTest2InodeUtilization MonitoringConstructAlarmFsvolVolTest2InodeUtilizationD3C7593B
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsvolRootStorageCapacityUtilization MonitoringConstructAlarmFsvolRootStorageCapacityUtilizationF51FEC6F
[+] AWS::CloudWatch::Alarm MonitoringConstruct/AlarmFsxnNumberOfBackupJobsFailed MonitoringConstructAlarmFsxnNumberOfBackupJobsFailedFE96A612

✨  Number of stacks with differences: 1

デプロイ後の各種リソースを確認します。

指定したSVMにボリュームが作成されていることを確認します。

3.ボリュームが作成されていること.png

ボリュームにバックアップ対象であることを示すBackupSelectionのタグが付与されていることを確認します。

5.ボリュームにBackupSelectionのタグが付与されていることを確認.png

実際にバックアップが行われたことを確認します。

6.バックアップが実行されたことを確認.png

設定したCloudWatchアラームの状態がNumberOfBackupJobsFailedを除いて、いずれもOKであることを確認します。

7.CloudWatchアラームが設定されていること.png

NumberOfBackupJobsFailedはバックアップが実際に失敗されないとPUTされないメトリクスです。実際に表示させたい場合は以下記事を参考にバックアップを失敗させる必要があります。

https://dev.classmethod.jp/articles/tsnote-backup-failed-aborted-metrics/

無理なくIaCを適用できそうなところからIaCを使ってみよう

AWS CDKでAmazon FSx for NetApp ONTAPの運用に必要なリソースをまとめてデプロイしてみました。

無理なくIaCを適用できそうなところからIaCを使ってみると良いかなと思います。

こちらのコードを流用する際は監視の閾値や命名規約などは調整してみてください。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.